﻿using Fuse8.ContentManagementFramework.Domain;
using Fuse8.ContentManagementFramework.Domain.Commands;
using Fuse8.ContentManagementFramework.Domain.Commands.CommandParameters;
using Fuse8.ContentManagementFramework.SystemFacade.Common;
using Fuse8.DomainFramework.BusinessService;
using Fuse8.DomainFramework.Common;
using Fuse8.DomainFramework.Common.Locator;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Fuse8.ContentManagementFramework.BizFacade.Services
{
    public class CmsMediaFileService : CmsSiteBusinessService<CmsMediaFile>
    {
        #region Override methods and event handlers

        protected override void OnCreating(EntityPreEventArgs<CmsMediaFile, int> e)
        {
            Guard.ArgumentNotNull(e, "e");

            if ((e.Entity != null) && string.IsNullOrEmpty(e.Entity.LinkedFileName))
            {
                e.Entity.LinkedFileName = FileNameGenerator.GenerateGuidName(Path.GetExtension(e.Entity.OriginalFileName));
            }

            base.OnCreating(e);
        }

        public override CmsMediaFile FindOne(int id)
        {
            var command = DependencyServiceLocator.Current.GetInstance<CmsMediaFileSelectOneCommand>();

            var commandParameter = new CmsMediaFileSelectOneCommandParameter
            {
                Id = id
            };

            SiteAwareEntityObjectMediator.SetSiteEntity(commandParameter);

            command.ConfigureCommand(commandParameter);

            return FindOne(command);
        }

        #endregion Override methods and event handlers

        #region Upload methods

        public CmsMediaFile UploadToMediaFile(string fileName, int? mimeTypeId, int fileLength)
        {
            return UploadToMediaFile(fileName, string.Empty, mimeTypeId, fileLength);
        }

        public CmsMediaFile UploadToMediaFile(string fileName, string linkedFileName, int? mimeTypeId, int fileLength)
        {
            return UploadToMediaFile(fileName, linkedFileName, mimeTypeId, fileLength, null, null, null);
        }

        public CmsMediaFile UploadToMediaFile(string fileName, string linkedFileName, int? mimeTypeId, int fileLength, int? imageHeight, int? imageWidth, int? existingFileId)
        {
            Guard.ArgumentNotEmpty(fileName, "fileName");

            CmsMediaFile result = null;

            if (existingFileId.HasValue)
            {
                result = FindOne(existingFileId.Value);
                //todo: remove physical file
            }

            if (result == null)
            {
                result = new CmsMediaFile();
            }

            result.OriginalFileName = fileName;
            result.LinkedFileName = linkedFileName;
            result.MimeTypeId = mimeTypeId;
            result.FileSize = fileLength;
            result.Height = imageHeight;
            result.Width = imageWidth;

            SiteAwareEntityObjectMediator.SetSiteEntity(result);

            if (result.IsNew)
            {
                Add(result);
            }
            else
            {
                Save(result);
            }

            return result;
        }

        #endregion Upload methods

        public IEnumerable<CmsMediaFile> FindByFolderIds(IEnumerable<int> ids)
        {
            if (ids != null && ids.Any())
            {
                var command = DependencyServiceLocator.Current.GetInstance<CmsMediaFileSelectByFolderIdsCommand>();

                var commandParameter = new CmsMediaFileSelectByFolderIdsCommandParameter
                {
                    Ids = string.Join(",", ids)
                };

                command.ConfigureCommand(commandParameter);

                return Find(command);
            }
            return null;
        }

        public void RemoveByIds(IEnumerable<int> ids)
        {
            if (ids != null && ids.Any())
            {
                var command = DependencyServiceLocator.Current.GetInstance<CmsMediaFileRemoveByIdsCommand>();

                var commandParameter = new CmsMediaFileRemoveByIdsCommandParameter
                {
                    Ids = string.Join(",", ids)
                };

                command.ConfigureCommand(commandParameter);

                Execute(command);
            }
        }
    }
}